package com.geo.common.result;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.time.LocalDateTime;

/**
 * 统一响应结果类
 * 
 * @author GEO Team
 * @version 1.0
 */
@Data
@NoArgsConstructor
public class Result<T> {
    
    /**
     * 响应代码
     */
    private String code;
    
    /**
     * 响应消息
     */
    private String message;
    
    /**
     * 响应数据
     */
    private T data;
    
    /**
     * 响应时间
     */
    private LocalDateTime timestamp;
    
    /**
     * 是否成功
     */
    private Boolean success;
    
    /**
     * 请求追踪ID
     */
    private String traceId;
    
    /**
     * 构造函数
     * @param code 响应代码
     * @param message 响应消息
     * @param data 响应数据
     * @param timestamp 响应时间
     * @param success 是否成功
     * @param traceId 请求追踪ID
     */
    public Result(String code, String message, T data, LocalDateTime timestamp, Boolean success, String traceId) {
        this.code = code;
        this.message = message;
        this.data = data;
        this.timestamp = timestamp;
        this.success = success;
        this.traceId = traceId;
    }
    
    /**
     * 成功响应
     * @param data 数据
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(
                ResultCode.SUCCESS.getCode(),
                ResultCode.SUCCESS.getMessage(),
                data,
                LocalDateTime.now(),
                true,
                generateTraceId()
        );
    }
    
    /**
     * 成功响应
     * @param message 消息
     * @param data 数据
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> success(String message, T data) {
        return new Result<>(
                ResultCode.SUCCESS.getCode(),
                message,
                data,
                LocalDateTime.now(),
                true,
                generateTraceId()
        );
    }
    
    /**
     * 成功响应（无数据）
     * @param message 消息
     * @return 响应结果
     */
    public static <T> Result<T> success(String message) {
        return new Result<>(
                ResultCode.SUCCESS.getCode(),
                message,
                null,
                LocalDateTime.now(),
                true,
                generateTraceId()
        );
    }
    
    /**
     * 失败响应
     * @param resultCode 结果代码
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> error(ResultCode resultCode) {
        return new Result<>(
                resultCode.getCode(),
                resultCode.getMessage(),
                null,
                LocalDateTime.now(),
                false,
                generateTraceId()
        );
    }
    
    /**
     * 失败响应
     * @param resultCode 结果代码
     * @param message 自定义消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> error(ResultCode resultCode, String message) {
        return new Result<>(
                resultCode.getCode(),
                message,
                null,
                LocalDateTime.now(),
                false,
                generateTraceId()
        );
    }
    
    /**
     * 失败响应
     * @param code 错误代码
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> error(String code, String message) {
        return new Result<>(
                code,
                message,
                null,
                LocalDateTime.now(),
                false,
                generateTraceId()
        );
    }
    
    /**
     * 失败响应（带数据）
     * @param resultCode 结果代码
     * @param message 自定义消息
     * @param data 错误数据
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> error(ResultCode resultCode, String message, T data) {
        return new Result<>(
                resultCode.getCode(),
                message,
                data,
                LocalDateTime.now(),
                false,
                generateTraceId()
        );
    }
    
    /**
     * 生成追踪ID
     * @return 追踪ID
     */
    private static String generateTraceId() {
        return "trace_" + System.currentTimeMillis() + "_" + Thread.currentThread().getId();
    }
    
    /**
     * 检查是否成功
     * @return 是否成功
     */
    public boolean isSuccess() {
        return Boolean.TRUE.equals(success);
    }
    
    /**
     * 检查是否失败
     * @return 是否失败
     */
    public boolean isFailed() {
        return !isSuccess();
    }
}